// Wrapper.h

#pragma once

#include "Jeu.h"
#include "Flotte.h"
#include <windows.h>
#include <vcclr.h>
#include <list>
#include <vector>
#include <utility>
#include <string>

#pragma comment (lib,"DLL_Cpp.lib")

using namespace System;

#using <mscorlib.dll>
#using <PresentationCore.dll>
#using <System.Windows.Forms.dll>
#using <System.Windows.Presentation.dll>
#using <PresentationFramework.dll>
#using <WindowsBase.dll>

namespace Wrapper {

	public ref class WrapperJeu
	{

	private:
		Jeu* _jeu;

	public:

		WrapperJeu(int nbJoueurs) {
			cout << "Nouveau jeu" << endl;
			_jeu = Jeu_New(nbJoueurs);
		}

		~WrapperJeu() {
			cout << "Suppresion jeu" << endl;
			Jeu_Delete(_jeu);
		}

	public:

		void creerPartie() {
			cout << "creerPartie()" << endl;
			_jeu->creerPartie();
		}

		unsigned int lancerDe() {
			return _jeu->lancerDe();
		}

		void addJoueur(System::String^  nom, System::String^  flotte1, System::String^  flotte2, int rang) {
			_jeu->addJoueur(stringSystemToSTL(nom), stringSystemToSTL(flotte1), stringSystemToSTL(flotte2), rang);
		}

		void addJoueur(System::String^ nom, System::String^ flotte, int rang) {

			_jeu->addJoueur(stringSystemToSTL(nom), stringSystemToSTL(flotte), rang);
		}

		void instancierGrille() {
			_jeu->instancierGrille();
		}

		unsigned int getLongueurPlateau() {
			return _jeu->getLongueurPlateau();
		}

		unsigned int getHauteurPlateau() {
			return _jeu->getHauteurPlateau();
		}

		int getTypeCase(int x, int y) {
			return _jeu->getTypeCase(x,y);
		}

		int getCouleurFlotte(int rangJoueur, int flotte) {
			return _jeu->getCouleurFlotte(rangJoueur, flotte);
		}

		bool joueurCourantHasArtefact() {
			return _jeu->joueurCourantHasArtefact();
		}

		int getTypeVaisseauCourant() {
			return _jeu->getTypeVaisseauCourant();
		}

		int getCouleurFlotteCourante() {
			return _jeu->getCouleurFlotteCourante();
		}

		int getNbArtefactsJoueurCourant() {
			return _jeu->getNbArtefactsJoueurCourant();
		}

		int getNbArtefactsCase(int x, int y) {
			return _jeu->getNbArtefactsCase(x,y);
		}

		int getTypeCaseVaisseauCourant() {
			return _jeu->getTypeCaseVaisseauCourant();
		}

		unsigned int getRangJoueurCourant() {
			return _jeu->getRangJoueurCourant();
		}

		int getNbChargesVaisseauCourant() {
			return _jeu->getNbChargesVaisseauCourant();
		}

		unsigned int getNbVaisseauxJoueurCourant() {
			return _jeu->getNbVaisseauxJoueurCourant();
		}

		void setPositionFlotteJoueur(int rang, int flotte, int x, int y) {
			_jeu->setPositionFlotteJoueur(rang,flotte,x,y);
		}
		
		int getXFlotteJoueur(int rang, int flotte) {
			return _jeu->getXFlotteJoueur(rang, flotte);
		}

		int getYFlotteJoueur(int rang, int flotte) {
			return _jeu->getYFlotteJoueur(rang, flotte);
		}

		void deplacerVaisseauCourant(int x, int y) {
			_jeu->deplacerVaisseauCourant(x,y);
		}

		void joueurSuivant() {
			_jeu->joueurSuivant();
		}

		int getXVaisseauCourant() {
			return _jeu->getXVaisseauCourant();
		}

		int getYVaisseauCourant() {
			return _jeu->getYVaisseauCourant();
		}

		int getNbJoueurs() {
			return _jeu->getNbJoueurs();
		}

		int getIndiceFlotteCourante() {
			return _jeu->getIndiceFlotteCourante();
		}
		
		int getCouleurStationCase(int x, int y) {
			return _jeu->getCouleurStationCase(x, y);
		}

		void setCouleurStationCase(int x, int y, int couleurStation) {
			_jeu->setCouleurStationCase(x, y, (Flotte::CouleurFlotte)couleurStation);
		}

		bool joueurCourantAGagne() {
			return _jeu->joueurCourantAGagne();
		}

		void setCaseAccessible(int x, int y, bool val) {
			_jeu->setCaseAccessible(x,y,val);
		}

		int downgradeVaisseau(int x, int y) {
			return _jeu->downgradeVaisseau(x,y);
		}

		int getXVaisseauTouche() {
			return _jeu->getXVaisseauTouche();
		}

		int getYVaisseauTouche() {
			return _jeu->getYVaisseauTouche();
		}

		bool getTouche() {
			return _jeu->getTouche();
		}

		int getTypeVaisseauTouche() {
			return _jeu->getTypeVaisseauTouche();
		}

		int getCouleurVaisseauTouche() {
			return _jeu->getCouleurVaisseauTouche();
		}
		
		bool vaisseauToucheHasArtefact() {
			return _jeu->vaisseauToucheHasArtefact();
		}

		int getTypeCaseVaisseauTouche() {
			return _jeu->getTypeCaseVaisseauTouche();
		}

		int getRangJoueurTouche() {
			return _jeu->getRangJoueurTouche();
		}

		int getIndiceFlotteTouche() {
			return _jeu->getIndiceFlotteTouche();
		}

		int getNbChargesVaisseauTouche() {
			return _jeu->getNbChargesVaisseauTouche();
		}

		int getNbArtefactsVaisseauTouche() {
			return _jeu->getNbArtefactsVaisseauTouche();
		}

		int getNbVaisseauVaisseauTouche() {
			return _jeu->getNbVaisseauVaisseauTouche();
		}

		System::Windows::Point getPointArrive(double x, double y, double resCos, double resSin) {
			return doublePairToPoint(_jeu->getPointArrive(x,y,resCos,resSin));
		}

		System::Windows::Point tirer(double x, double y, double resCos, double resSin) {
			return doublePairToPoint(_jeu->tirer(x,y,resCos,resSin));
		}

		String^ getNomJoueur(int rang) {
			return stringSTLToSystem(_jeu->getNomJoueur(rang));
		}

		System::Collections::Generic::List<unsigned int>^ lancerDesJoueurCourant() {
			return vectorToList(_jeu->lancerDesJoueurCourant());
		}
		
		System::Collections::Generic::List<System::Windows::Shapes::Polygon^>^ getListePolygoneAsteroide() {
			return doublePairVectorVectorToPolygonList(_jeu->getVectorAsteroides());
		}

		System::Collections::Generic::List<System::Windows::Point>^ getCasesAccessibles(unsigned int res) {
			return doublePairVectorToPointList(_jeu->getCasesAccessibles(res));
		}

	public :

		System::Collections::Generic::List<System::Windows::Point>^ doublePairVectorToPointList(std::vector<std::pair<double, double> > src)
		{
			int size = src.size();
			System::Collections::Generic::List<System::Windows::Point>^ dest = gcnew System::Collections::Generic::List<System::Windows::Point>();
			for(int i = 0 ; i < size ; i++){
				dest->Add(doublePairToPoint(src[i]));
			}
			return dest;
		}

		string stringSystemToSTL(String^ string) {
                char* tmp = static_cast<char *>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(string).ToPointer());
                std::string res(tmp);
                System::Runtime::InteropServices::Marshal::FreeHGlobal(IntPtr(tmp));
                return res;
        }

		String^ stringSTLToSystem(string string) {
			return gcnew String(string.c_str());
        }

		System::Collections::Generic::List<unsigned int>^ vectorToList(std::vector<unsigned int> v) {
                System::Collections::Generic::List<unsigned int>^ res = gcnew System::Collections::Generic::List<unsigned int>();
                unsigned int i;
                for(i=0;i<v.size();i++){
                        res->Add(v[i]);
                }
                return res;
        }

		System::Collections::Generic::List<System::Windows::Shapes::Polygon^>^ doublePairVectorVectorToPolygonList(std::vector<std::vector<std::pair<double, double> > > src)
		{
			int size = src.size();
			System::Collections::Generic::List<System::Windows::Shapes::Polygon^>^ dest = gcnew System::Collections::Generic::List<System::Windows::Shapes::Polygon^>();
			for(int i = 0 ; i < size ; i++){
				System::Windows::Shapes::Polygon^ tmpPoly = gcnew System::Windows::Shapes::Polygon();
				System::Windows::Media::PointCollection^ tmpPoints = gcnew System::Windows::Media::PointCollection();
				for(unsigned j=0 ; j<src[i].size() ; j++){
					tmpPoints->Add(doublePairToPointAsteroide(src[i][j]));
				}
				tmpPoly->Points = tmpPoints;
				dest->Add(tmpPoly);
			}
			return dest;
		}

		System::Windows::Point doublePairToPointAsteroide(std::pair<double, double> src)
		{
			return System::Windows::Point(src.first*67, src.second*63);
		}

		System::Windows::Point doublePairToPoint(std::pair<double, double> src)
		{
			return System::Windows::Point(src.first, src.second);
		}

	};
}
